use model_graph_common::utils::rrg01_home_path;
use model_graph_types::{
    container::context::Context,
    database::{ConnectorProtocol, DataSource, DatabaseType},
    datasource::DataSourceProvider,
    modeling::set_system_meta_database,
};

pub mod handlers;
// pub mod middleware;
pub(crate) mod services;
pub(crate) mod utils;
pub(crate) mod workers;

pub use datasource_connector;
pub use model_graph_types;

#[derive(Debug, Default, Clone)]
pub struct AppState {
    pub app_name: String,
    pub context: Arc<Mutex<Context>>,
}

use std::{
    env,
    sync::{Arc, Mutex},
};

pub fn default_database() -> DataSource {
    let url = env::var("DATABASE_URL").expect("db name not set!");

    DataSource {
        database_type: DatabaseType::MySQL,
        protocol: ConnectorProtocol::MySQL,
        url: url,
        ..Default::default()
    }
}

pub fn scheduler_enable() -> bool {
    env::var("SCHEDULER").map_or(true, |v| !(v.to_lowercase() == String::from("false")))
}

pub fn meta_database() -> DataSource {
    let db_path = rrg01_home_path()
        .expect("没有设置RRG01_PATH!")
        .join("rrg01.sqlite");

    DataSource {
        database_type: DatabaseType::SQLite,
        protocol: ConnectorProtocol::SQLite,
        url: format!(
            "sqlite:{}",
            db_path
                .to_str()
                .map_or(Err(anyhow::anyhow!("")), |v| Ok(v))
                .expect("没有设置系统库!")
        ),
        ..Default::default()
    }
}

/// start
pub async fn start() -> anyhow::Result<AppState> {
    //设置系统库
    set_system_meta_database(meta_database())?;

    //启动worker
    if scheduler_enable() {
        workers::start().await?;
    }
    let mut context = Context::default();

    context.set_default_datasource(default_database()).await?;

    Ok(AppState {
        app_name: String::from("G01"),
        context: Arc::new(Mutex::new(context)),
    })
}
